<?php
	require_once(dirname(__FILE__)."/../../../config.php");
?>
<?php
/*
 * WidgetFramework Encryption Module
 * Created: 200904 (TT Tsai)
 *
 * encryption and decryption
 */
class WFCrypt {
	// settings
	private $keyfile;
	private $algorithm;

	// main descriptor
	private $cipher;
	private $init_vector;
	private $key_size;
	private $key;

	// error handling
	private $errMessage = "";

	// Constructor
	public function __construct() {
		$this->keyfile = $GLOBALS['wfconf_wfcrypt_keyfile'];
		$this->algorithm = $GLOBALS['wfconf_wfcrypt_algorithm'];
		// open the cipher
		$this->cipher = mcrypt_module_open($this->algorithm, '', MCRYPT_MODE_ECB, '');
		if( $this->cipher == FALSE ) {
			$this->errMessage = "mcrypt_module_open() failed.";
			return;
		}
		// create IV
		$this->init_vector = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->cipher), MCRYPT_RAND);
		if( $this->init_vector == FALSE ) {
			$this->errMessage = "mcrypt_create_iv() failed.";
			return;
		}
		// key size
		$this->key_size = mcrypt_enc_get_key_size($this->cipher);
		// load key
		if( $this->key_load() == FALSE ) {
			// no key, I will generate one
			$this->key_gen();
			// write to file
			if( $this->key_dump() == FALSE ) {
				$this->errMessage = "failed to generate key.";
				return;
			}
		}
		// make sure key length
		$this->key = substr( $this->key, 0, $this->key_size);
	}

	// init
	public function init() {
		// Intialize encryption
		$ret = mcrypt_generic_init($this->cipher, $this->key, $this->init_vector);
		/* weird
		if( $ret == FALSE ) {
			$this->errMessage = "mcrypt_generic_init() failed: parameter error.";
			return;
		}
		*/
		if( $ret < 0 ) {
			if( $ret == -3 ) {
				$this->errMessage = "mcrypt_generic_init() failed: key length was incorrect.";
			}
			else if( $ret == -4 ) {
				$this->errMessage = "mcrypt_generic_init() failed: there was a memory allocation problem.";
			}
			else {
				$this->errMessage = "mcrypt_generic_init() failed: unknown error.";
			}
			return;
		}
		// init done
	}

	// deinit
	public function deinit() {
		// Terminate encryption handler
		if( mcrypt_generic_deinit($this->cipher) == FALSE ) {
			$this->errMessage = "mcrypt_generic_deinit() failed.";
		}
	}

	// Desctructor
	public function __destruct() {
		// close module
		if( mcrypt_module_close($this->cipher) == FALSE ) {
			$this->errMessage = "mcrypt_module_close() failed.";
		}
	}

	/*
	 * public methods
	 */
	// encrypt
	public function encrypt( $plain_str ) {
		// need init
		$this->init();
		if( $this->isFailed() ) {
			return;
		}
		if(!empty($plain_str))
		{
			$enc_str = mcrypt_generic( $this->cipher, $plain_str);
		}
		else
		{
			$this->deinit();
			return "";
		}
		// need deinit
		$this->deinit();
		return base64_encode($enc_str);
	}

	// decrypt
	public function decrypt( $enc_str ) {
		// need init
		$this->init();
		if( $this->isFailed() ) {
			return;
		}
		if(!empty($enc_str))
		{
			$plain_str = mdecrypt_generic( $this->cipher, base64_decode($enc_str));
		}
		else
		{
			$this->deinit();
			return "";
		}
		// need deinit
		$this->deinit();
		return trim($plain_str, "\0");
	}

	/*
	 * key management
	 */
	// generate key
	public function key_gen() {
		$this->key = "";
		$charset = "abcdefghijklmnopqrstuvwxyz";
		$charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		$charset .= "0123456789";
		$charset .= "~!@#$%^&*()_+`-={}|\\]?[\":;'><,./";
		for( $i=0; $i < $this->key_size; $i++) {
			$this->key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
		}
	}
	// load key
	public function key_load( $file = null ) {
		if( $file == null ) {
			$file = $this->keyfile;
		}

		// key file exist?
		if( ! file_exists($file) ) {
			return FALSE;
		}
		// read data from file
		$this->key = file_get_contents($this->keyfile);
		if( $this->key == FALSE ) {
			return FALSE;
		}
		return TRUE;
	}
	// dump key
	public function key_dump( $file = null, $content = null) {
		if( $file == null ) {
			$file = $this->keyfile;
		}
		if( $content == null ) {
			$content = $this->key;
		}
		if( file_put_contents($file, $content) == FALSE ) {
			return FALSE;
		}
		return TRUE;
	}

	/*
	 * Error handling
	 */
	public function isFailed() {
		if( $this->errMessage != "" ) {
			return TRUE;
		}
		return FALSE;
	}
	public function getErrMessage() {
		return $this->errMessage;
	}
}
?>
